import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import javax.xml.transform.*;

public class Server extends HttpServlet {
    public void doGet(HttpServletRequest request, 
		      HttpServletResponse response)
	throws ServletException {
	response.setContentType("text/xml");
	PrintWriter out = null;
	try {
	    out = response.getWriter();
	}
	catch(IOException e) {
	    throw new ServletException("Unable to create writer "+
				       e.getMessage());
	}
	String req = request.getParameter("word");
	if(req==null) {
	    try {
		CreateListing.main(null);
	    }
	    catch(Exception e) {
		throw new ServletException("Unable to create listing of documents "+e);
	    }
	    req = "listing.xml";
	}
	else {
	    req += ".xml";
	}
	SAXBuilder b = new SAXBuilder();
	File file = null;
	try {
	    file = new File("webapps/Wiki/WEB-INF/documents/"+req);
	}
	catch(NullPointerException e) {
	    throw new ServletException("Unable to open file "+
				       e.getMessage());
	}
	Document doc = null;
	try {
	    doc = b.build(file);
	}
	catch(JDOMException e) {
	    throw new ServletException("Unable to parse file "+
				       e.getMessage());
	}
	catch(IOException e) {
	    throw new ServletException("Unable to read from file "+
				       e.getMessage());
	}
	XMLOutputter outputter = new XMLOutputter();
	try {
	    outputter.output(doc, out);
	}
	catch(IOException e) {
	    throw new ServletException("Unable to output document "+
				       e.getMessage());
	}
	finally {
	    out.close();
	}
    }
    public void doPut(HttpServletRequest request,
		       HttpServletResponse response)
	throws ServletException {
	String word = request.getParameter("word");
	if(word==null) {
	    throw new ServletException("Missing parameter 'word'");
	}
       	BufferedReader reader = null;
	try {
	    reader = request.getReader();
	}
	catch(UnsupportedEncodingException e) {
	    throw new ServletException("Character set encoding is not supported "+
				       e.getMessage());
	}
	catch(IllegalStateException e) {
	    throw new ServletException("getInputStream() has already been called "+
				       e.getMessage());
	}
	catch(IOException e) {
	    throw new ServletException("Unable to create reader "+
				       e.getMessage());
	}

	SAXBuilder b = new SAXBuilder();
	b.setValidation(true);
        b.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
		      "http://www.w3.org/2001/XMLSchema");
	b.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
		      "webapps/Wiki/WEB-INF/source/WikiXML.xsd");
	Document doc = null;
	try {
	    doc = b.build(reader);
	}
	catch(JDOMException e) {
	    throw new ServletException("Unable to parse document against schema "+
				       e.getMessage());
	}
	catch(IOException e) {
	    throw new ServletException("Unable to read from request body "+
				       e.getMessage());
	}
	writeDocument(doc, word);
	try {
	    reader.close();
	}
	catch(IOException e) {
	    throw new ServletException("Unable to close reader "+
				       e.getMessage());
	}
    }
    /**
     * The filewriting is extracted from the doPut method because
     * we wish to synchronize only that.
     */
    private synchronized void writeDocument(Document doc, 
					       String word) 
	throws ServletException {
	File file = null;
	try {
	    file = new File("webapps/Wiki/WEB-INF/documents/"+word+".xml");
	}
	catch(NullPointerException e) {
	    throw new ServletException("Unable to open file "+
				       e.getMessage());
	}
	FileWriter writer = null;
	try {
	    writer = new FileWriter(file);
	}
	catch(IOException e) {
	    throw new ServletException("Unable to create filewriter "+
				       e.getMessage());
	}
	XMLOutputter outputter = new XMLOutputter();
	try {
	    outputter.output(doc, writer);
	}
	catch(IOException e) {
	    throw new ServletException("Unable to write to file "+
				       e.getMessage());
	}
    }
    public void doDelete(HttpServletRequest request,
			 HttpServletResponse response)
	throws ServletException {
	String word = request.getParameter("word");
	if(word==null) {
	    throw new ServletException("Missing parameter 'word'");
	}
	deleteDocument(word);
    }
    /**
     * The deletion is extracted from the doDelete method because
     * we wish to synchronize only that.
     */
    private synchronized void deleteDocument(String word) 
	throws ServletException {
	File file = null;
	try {
	    file = new File("webapps/Wiki/WEB-INF/documents/"+word+".xml");
	}
	catch(NullPointerException e) {
	    throw new ServletException("Unable to open file "+
				       e.getMessage());
	}
	if(!file.isFile()) {
	    throw new ServletException("Document '"+word+"' doesn't excist");
	}
	if(!file.delete()) {
	    throw new ServletException("Document '"+word+"' could not be deleted");
	}
    }
}
